<?php


namespace App\Models;


use App\Http\Resources\Base\BaseResource;
use App\Http\Resources\Bike\BikeResource;
use App\Http\Resources\UserBike\UserBikeResource;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Storage;
use ImageSizes;
use League\CommonMark\Inline\Element\Image;

class UserBike extends BaseModel {
    use SoftDeletes;

    private static $searchFields = [
        "isSearch",
        "isOwn",
        "authorId",
        "isNotSearch",
        "author",
        "bookmark",
        "isDeleted",
        "page",
        "serial",
        "brand",
        "category",
        "title",
        "main_brand",
    ];
    protected $table = "users_bikes";
    public $timestamps = true;
    protected $fillable = [
        'status',
        'confirmed',
        'users_id',
        'bikes_id',
        'country',
        'city',
        'address',
        'deleted_at',
        'privacy'
    ];
    //protected $dates = [ 'deleted_at' ];
    private $session;

    public function makeSave() {
        $this->address=$this->address??'';
        return parent::makeSave();
    }

    public function getBike(): HasOne {
        return $this->hasOne( "App\Models\Bike", "id", "bikes_id" );
    }

    public function getUser(): HasOne {
        return $this->hasOne( "App\Models\User", "id", "users_id" );
    }

    public function delete(): ?bool {
        $this->getBike()->delete();

        return parent::delete();
    }

    public static function getBikeBySerial( $serial ): ?array {
        $bike = ( new BikeResource( Bike::where( "serial", $serial )->first() ) )->toArray();

        if ( $bike != null ) {
            return ( new UserBikeResource( UserBike::where( "bikes_id", $bike["id"] )->first() ) )->toArray();
        }

        return null;
    }

    public static function getAllSearch( $limit = 10, $offset = 0 ): array {
        global $request;

        return ( UserBikeResource::collection( UserBike::where( "status", 2 )->skip( $offset )->limit( $limit )->get() ) )->toArray( $request );
    }

    public static function getAllBikes(): array {
        global $request;

        return ( UserBikeResource::collection( UserBike::withTrashed()->orderBy( "id" )->get() ) )->toArray( $request );

    }


    public static function searchFilter() {
        global $request;
        $per_page = $request->input( "per_page" ) ?? 10;
        $page     = $request->input( "page" ) ?? 1;
        $all_bike = UserBike::leftJoin( 'bikes', 'users_bikes.bikes_id', '=', 'bikes.id' );

        foreach ( self::$searchFields as $field ) {
            if ( $request->input( $field ) != null && ( $request->input( $field ) != 0 || $request->input( $field ) != "" ) ) {

                switch ( $field ) {
                    case "isSearch":

                        $all_bike->where( "users_bikes.status", 2 );
                        break;
                    case "isOwn":
                        $all_bike->orWhere( "users_bikes.status", 1 );
                        break;
                    case "author":
                        if ( Auth::check() ) {
                            $all_bike->where( "users_bikes.users_id", auth()->user()->id );
                        }
                        break;
                    case "authorId":
                        $all_bike->where( "users_bikes.users_id", $request->input( "authorId" ) );
                        break;
                    case "bookmark":
                        if ( Auth::check() ) {
                            $all_bike->leftJoin( 'bookmarks', 'bookmarks.bikes_id', '=', 'users_bikes.bikes_id' )->
                            where( "bookmarks.users_id", auth()->user()->id )->
                            where( "bookmarks.deleted_at", null );
                        }
                        break;
                    case "isDeleted":
                        if ( Auth::check() ) {
                            $all_bike->withTrashed()->where( "users_bikes.users_id", auth()->user()->id );
                        }
                        break;
                    case "serial":
                        $all_bike->orWhere( "bikes.serial", 'LIKE', '%' . $request->input( $field ) . '%' );
                        break;
                    case "brand":
                        $all_bike->leftJoin( 'components', function ( $join ) {
                            $join->on( 'bikes.brand', '=', 'components.id' );
                            $join->orOn( 'bikes.equipment_group', '=', 'components.id' );
                            $join->orOn( 'bikes.pedals', '=', 'components.id' );
                            $join->orOn( 'bikes.carriage', '=', 'components.id' );
                            $join->orOn( 'bikes.cassette', '=', 'components.id' );
                            $join->orOn( 'bikes.planetary_hub', '=', 'components.id' );
                            $join->orOn( 'bikes.singspeed', '=', 'components.id' );
                            $join->orOn( 'bikes.connecting_rods', '=', 'components.id' );
                            $join->orOn( 'bikes.chainring', '=', 'components.id' );
                            $join->orOn( 'bikes.chain', '=', 'components.id' );
                            $join->orOn( 'bikes.shifters', '=', 'components.id' );
                            $join->orOn( 'bikes.front_switch', '=', 'components.id' );
                            $join->orOn( 'bikes.rear_switch', '=', 'components.id' );
                            $join->orOn( 'bikes.roller_skates', '=', 'components.id' );
                            $join->orOn( 'bikes.switch_rollers', '=', 'components.id' );
                            $join->orOn( 'bikes.aerobar', '=', 'components.id' );
                            $join->orOn( 'bikes.steering_wheel', '=', 'components.id' );
                            $join->orOn( 'bikes.grips', '=', 'components.id' );
                            $join->orOn( 'bikes.handlebar_winding', '=', 'components.id' );
                            $join->orOn( 'bikes.steering_column', '=', 'components.id' );
                            $join->orOn( 'bikes.stem', '=', 'components.id' );
                            $join->orOn( 'bikes.rigid_fork', '=', 'components.id' );
                            $join->orOn( 'bikes.shock_absorber_26', '=', 'components.id' );
                            $join->orOn( 'bikes.shock_absorber_27_5', '=', 'components.id' );
                            $join->orOn( 'bikes.shock_absorber_29', '=', 'components.id' );
                            $join->orOn( 'bikes.shock_absorber_700с', '=', 'components.id' );
                            $join->orOn( 'bikes.spring', '=', 'components.id' );
                            $join->orOn( 'bikes.rear_shock_absorber', '=', 'components.id' );
                            $join->orOn( 'bikes.rim_brakes', '=', 'components.id' );
                            $join->orOn( 'bikes.disc_brake', '=', 'components.id' );
                            $join->orOn( 'bikes.brake_levers', '=', 'components.id' );
                            $join->orOn( 'bikes.saddle', '=', 'components.id' );
                            $join->orOn( 'bikes.seatpost', '=', 'components.id' );
                            $join->orOn( 'bikes.cushioned_seatpost', '=', 'components.id' );
                            $join->orOn( 'bikes.telescopic_seatpost', '=', 'components.id' );
                            $join->orOn( 'bikes.wheels_26', '=', 'components.id' );
                            $join->orOn( 'bikes.wheels_27', '=', 'components.id' );
                            $join->orOn( 'bikes.wheels_29', '=', 'components.id' );
                            $join->orOn( 'bikes.wheels_700C', '=', 'components.id' );
                            $join->orOn( 'bikes.rims', '=', 'components.id' );
                            $join->orOn( 'bikes.tires', '=', 'components.id' );
                            $join->orOn( 'bikes.inner_tire', '=', 'components.id' );
                            $join->orOn( 'bikes.sleeve', '=', 'components.id' );
                            $join->orOn( 'bikes.drum_bushing', '=', 'components.id' );
                            $join->orOn( 'bikes.power_connecting_rods', '=', 'components.id' );
                            $join->orOn( 'bikes.power_pedals', '=', 'components.id' );

                        } )->distinct()->orWhere( "components.brand_list", 'LIKE', $request->input( $field ) . '%' )->orWhere( "components.model_list", 'LIKE', '%' . $request->input( $field ) . '%' );
                        break;
                    case "category":
                        $all_bike->leftJoin( 'bikes_categories', 'bikes_categories.id', '=', 'bikes.bikes_categories_id' )->
                        orWhere( "bikes_categories.title", 'LIKE', '%' . $request->input( $field ) . '%' );
                        break;
                    case "title":
                        $title_list   = [ 'brand', 'model', 'year' ];
                        $all_producer = Components::where( 'type', 'brand' )->pluck( 'brand_list' )->toArray();
                        $full_title   = $request->input( $field );
                        $ar_params    = [];
                        foreach ( $all_producer as $producer ) {
                            if ( stripos( $full_title, $producer ) !== false ) {
                                $full_title   = trim(str_replace( $producer, '', $full_title ));
                                $ar_params[0] = $producer;
                            }
                        }

                        $ar_params = array_merge($ar_params,explode( " ", $full_title ));
                        $len       = count( $ar_params );
                        if ( $len > 3 ) {
                            $ar_params[1] = implode( ' ', array_slice( $ar_params, 1, $len - 2 ) );
                            $ar_params[2] = $ar_params[ $len - 1 ];
                            $ar_params    = array_slice( $ar_params, 0, 3 );
                        }
                        $all_bike->orWhere( function ( $query ) use ( $ar_params, $title_list ) {
                            foreach ( $ar_params as $key => $item ) {
                                $query->where( "bikes.{$title_list[$key]}", 'LIKE', "%$item%" );
                            }
                        } );
                        break;
                }
            }
        }
        $select = $all_bike->select( "users_bikes.*" );

        return [
            "all_count" => count( $select->get() ),
            "page"      => $page,
            "bikes"     => ( $per_page > 0 ? $select->skip( ( $page - 1 ) * $per_page )->limit( $per_page ) : $select )->get(),
            "white"     => (bool) $request->input( "white" )
        ];


    }

    public function makeDelete() {
        $all_files_ids=UserFile::whereIn('id',BikeFile::where( 'bikes_id', $this->bikes_id )->pluck( 'files_id' )->toArray())->pluck('id')->toArray();
        $this->deleteFiles(UserFile::whereIn('id',$all_files_ids)->get());
        $this->deleteFiles(ImageSize::whereIn('images_id',$all_files_ids)->get());
        $q      = 'DELETE bikes, bike_files,files,bookmarks,users_bikes_likes FROM bikes
                    LEFT JOIN bike_files ON bike_files.bikes_id=bikes.id
                    LEFT JOIN files ON bike_files.files_id=files.id
                    LEFT JOIN bookmarks ON bookmarks.bikes_id=bikes.id
                    LEFT JOIN users_bikes_likes ON users_bikes_likes.bikes_id=bikes.id
                    WHERE bikes.id=?
        ';

        DB::delete( $q, [ $this->bikes_id ] );

        return $this->forceDelete();
    }

    private function deleteFiles($files=null){
        if($files){
            foreach($files as $file){
                $file->delete();
            }
        }
    }


}
